using System;
using System.Collections.Generic;
using System.Text;
using EastBancTech.DSL.FileSystemDefinition;
using System.IO;
using Microsoft.VisualStudio.Modeling;
using System.Xml;

namespace EastBancTech.InstallerDefinition.Mapping
{
    public class InstallerDef2WixMapping
    {
        Store Store = null;

        public InstallerDef2WixMapping(Store store)
        {
            Store = store;
        }

        private String GetFileId(FileModel fileModel)
        {
            return NormalizeId(Path.GetFileName(fileModel.Name) + "." + GetElementGuid(fileModel.GetUniqueName()));
        }

        private string NormalizeId(string p)
        {
            throw new Exception("The method or operation is not implemented.");
        }

        private string GetElementGuid(string p)
        {
            throw new Exception("The method or operation is not implemented.");
        }

        public Microsoft.Tools.WindowsInstallerXml.Serialize.Module CreateWixModule(InstallerPackageModel installerModel)
        {
            Microsoft.Tools.WindowsInstallerXml.Serialize.Module module = new Microsoft.Tools.WindowsInstallerXml.Serialize.Module();
            module.Id = installerModel.ProductName;
            module.Guid = installerModel.ProductCode.ToString();
            module.Language = installerModel.LocaleId.ToString();
            module.Version = installerModel.ProductVersion;
            if (installerModel.CodePage != 0)
                module.Codepage = installerModel.CodePage;

            module.AddChild(CreateWixPackage(installerModel));

            return module;
        }

        public Microsoft.Tools.WindowsInstallerXml.Serialize.Package CreateWixPackage(InstallerPackageModel installerModel)
        {
            Microsoft.Tools.WindowsInstallerXml.Serialize.Package package = new Microsoft.Tools.WindowsInstallerXml.Serialize.Package();
            package.Id = Guid.NewGuid().ToString();
            package.InstallerVersion = 200;
            package.Comments = installerModel.Comments;
            package.Description = installerModel.Description;
            package.Manufacturer = installerModel.Manufacture;
            package.Platforms = "Intel";
            package.Languages = installerModel.LocaleId.ToString();
            package.SummaryCodepage = installerModel.CodePage != 0 ? installerModel.CodePage.ToString() : "1252";

            return package;
        }
        
        public Microsoft.Tools.WindowsInstallerXml.Serialize.Fragment GenerateInstallUtilActions(ComponentFileSource componentFS)
        {
            Microsoft.Tools.WindowsInstallerXml.Serialize.Fragment fragment = new Microsoft.Tools.WindowsInstallerXml.Serialize.Fragment();
            Microsoft.Tools.WindowsInstallerXml.Serialize.InstallExecuteSequence installExecSeq = new Microsoft.Tools.WindowsInstallerXml.Serialize.InstallExecuteSequence();
            
            foreach (FileModel file in GetAllFileForFileSysytem(componentFS))
            {
                if (componentFS.IsFileInstallUtil(file.Path))
                    AddInstallUtilComponent(file, fragment, installExecSeq);
            }
                        
            fragment.AddChild(installExecSeq);

            return fragment;
        }

        public List<FileModel> GetAllFileForFileSysytem(ComponentFileSource componentFS)
        {
            List<FileModel> list = new List<FileModel>();

            if (componentFS == null || componentFS.FileSystem == null)
                return list;

            foreach (DirectoryModel dir in componentFS.FileSystem.Directories)
                foreach (FileModel f in GetAllFileForDirectory(dir))
                    list.Add(f);

            return list;
        }

        public List<FileModel> GetAllFileForDirectory(DirectoryModel directory)
        {
            List<FileModel> list = new List<FileModel>();

            foreach (FileModel file in directory.Files)
                list.Add(file);


            return list;
        }

        private void AddInstallUtilComponent(FileModel file, Microsoft.Tools.WindowsInstallerXml.Serialize.Fragment fragment, Microsoft.Tools.WindowsInstallerXml.Serialize.InstallExecuteSequence installExecSeq)
        {
            // <wix:CustomAction Id="chafbhhi_bafe_dfed_ajee_ddahebbdfidc.install" Return="check" Execute="deferred" BinaryKey="InstallUtil" DllEntry="ManagedInstall" />
            //<wix:CustomAction Id="chafbhhi_bafe_dfed_ajee_ddahebbdfidc.install.SetProperty" Return="check" Property="chafbhhi_bafe_dfed_ajee_ddahebbdfidc.install" Value="/installtype=notransaction /action=install /LogFile= &quot;[#chafbhhi_bafe_dfed_ajee_ddahebbdfidc]&quot; &quot;[VSDFxConfigFile]&quot;">
            //</wix:CustomAction>
            Microsoft.Tools.WindowsInstallerXml.Serialize.CustomAction ca = new Microsoft.Tools.WindowsInstallerXml.Serialize.CustomAction();
            ca.Id = GetFileId(file) + "." + "install";
            ca.Return = Microsoft.Tools.WindowsInstallerXml.Serialize.CustomAction.ReturnType.check;
            ca.Execute = Microsoft.Tools.WindowsInstallerXml.Serialize.CustomAction.ExecuteType.deferred;
            ca.BinaryKey = "InstallUtil";
            ca.DllEntry = "ManagedInstall";
            fragment.AddChild(ca);

            ca = new Microsoft.Tools.WindowsInstallerXml.Serialize.CustomAction();
            ca.Id = GetFileId(file) + "." + "install.SetProperty";
            ca.Return = Microsoft.Tools.WindowsInstallerXml.Serialize.CustomAction.ReturnType.check;
            ca.Execute = Microsoft.Tools.WindowsInstallerXml.Serialize.CustomAction.ExecuteType.deferred;
            ca.Property = GetFileId(file) + "." + "install";
            ca.Value = String.Format("/installtype=notransaction /action=install /LogFile= &quot;[#{0}]&quot; &quot;[VSDFxConfigFile]&quot;", file.Id);
            fragment.AddChild(ca);

            //<wix:Custom Action="chafbhhi_bafe_dfed_ajee_ddahebbdfidc.install.SetProperty" After="StartServices">$adadbbdf_ahbd_dfdi_bgac_fcaiaaadbejb_C&gt;2</wix:Custom>
            //<wix:Custom Action="chafbhhi_bafe_dfed_ajee_ddahebbdfidc.install" After="chafbhhi_bafe_dfed_ajee_ddahebbdfidc.install.SetProperty">$adadbbdf_ahbd_dfdi_bgac_fcaiaaadbejb_C&gt;2</wix:Custom>

            Microsoft.Tools.WindowsInstallerXml.Serialize.Custom caRef = new Microsoft.Tools.WindowsInstallerXml.Serialize.Custom();
            caRef.Action = GetFileId(file) + "." + "install.SetProperty";
            caRef.After = "StartServices";
            caRef.Content = String.Format("#{0}>2", file.Id);
            installExecSeq.AddChild(caRef);

            caRef = new Microsoft.Tools.WindowsInstallerXml.Serialize.Custom();
            caRef.Action = GetFileId(file) + "." + "install";
            caRef.After = GetFileId(file) + "." + "install.SetProperty"; ;
            caRef.Content = String.Format("#{0}>2", file.Id);
            installExecSeq.AddChild(caRef);

        }

         public Microsoft.Tools.WindowsInstallerXml.Serialize.Fragment GenerateVirtualDirProperties(Definitions definitions)
        {
            Microsoft.Tools.WindowsInstallerXml.Serialize.Fragment fragment = new Microsoft.Tools.WindowsInstallerXml.Serialize.Fragment();

            foreach (VirtualDirectoryProperties vdirProp in definitions.VirtualDirectoryProperties)
            {
                fragment.AddChild(GenerateWixWebDirProperties(vdirProp));
            }

            return fragment;
        }

        public void GenerateIISStaff(IIS iis, Microsoft.Tools.WindowsInstallerXml.Serialize.DirectoryRef targetRef, Microsoft.Tools.WindowsInstallerXml.Serialize.ComponentGroup cg)
        {
            Microsoft.Tools.WindowsInstallerXml.Serialize.Component component = null;
            Microsoft.Tools.WindowsInstallerXml.Serialize.ComponentRef cr = null;

            foreach (IISApplicationPool iisPool in iis.AppPools)
            {
                component = new Microsoft.Tools.WindowsInstallerXml.Serialize.Component();
                component.AddChild(GetIIS60Condition());
                component.Id = GetAppPoolComponentId(iisPool);
                component.Guid = GetComponentGuid(component.Id);
                component.Permanent = Microsoft.Tools.WindowsInstallerXml.Serialize.YesNoType.yes;
                component.AddChild(GenerateWixApplicationPool(iisPool));
                component.AddChild(GenerateWixUserForAppPool(iisPool));

                cr = new Microsoft.Tools.WindowsInstallerXml.Serialize.ComponentRef();
                cr.Id = component.Id;
                cg.AddChild(cr);
                targetRef.AddChild(component);

                GetCurrentFragment().AddChild(GetWixProperty(GetAppPoolUserNameProperty(iisPool), ""));
                GetCurrentFragment().AddChild(GetWixProperty(GetAppPoolUserPasswordProperty(iisPool), ""));
                GetCurrentFragment().AddChild(GetWixProperty(GetAppPoolUserDomainProperty(iisPool), ""));
            }

            foreach (WebSite webSite in iis.WebSites)
            {
                component = new Microsoft.Tools.WindowsInstallerXml.Serialize.Component();
                component.Id = GetWebSiteComponentId(webSite);
                component.Guid = GetComponentGuid(component.Id);
                component.Permanent = Microsoft.Tools.WindowsInstallerXml.Serialize.YesNoType.yes;
                component.AddChild(GenerateWixWebSite(webSite));
                cr = new Microsoft.Tools.WindowsInstallerXml.Serialize.ComponentRef();
                cr.Id = component.Id;
                cg.AddChild(cr);
                targetRef.AddChild(component);
            }
        }

        private Microsoft.Tools.WindowsInstallerXml.Serialize.WebApplicationExtension CreateNewWebAppExtension(
            String Extension,
            Microsoft.Tools.WindowsInstallerXml.Serialize.YesNoType CheckPath,
            Microsoft.Tools.WindowsInstallerXml.Serialize.YesNoType Script,
            String Executable,
            String Verbs)
        {
            Microsoft.Tools.WindowsInstallerXml.Serialize.WebApplicationExtension ext = new Microsoft.Tools.WindowsInstallerXml.Serialize.WebApplicationExtension();
            ext.Extension = Extension;
            ext.CheckPath = CheckPath;
            ext.Executable = Executable;
            ext.Script = Script;
            ext.Verbs = Verbs;

            return ext;
        }

        public List<Microsoft.Tools.WindowsInstallerXml.Serialize.WebApplicationExtension> GetWebAppExtensionsForAspNet2_0()
        {
            List<Microsoft.Tools.WindowsInstallerXml.Serialize.WebApplicationExtension> list = new List<Microsoft.Tools.WindowsInstallerXml.Serialize.WebApplicationExtension>();
            list.Add(CreateNewWebAppExtension("ad", Microsoft.Tools.WindowsInstallerXml.Serialize.YesNoType.yes, Microsoft.Tools.WindowsInstallerXml.Serialize.YesNoType.yes, "[ASPNETISAPIDLL]", "GET,HEAD,POST"));
            list.Add(CreateNewWebAppExtension("ad", Microsoft.Tools.WindowsInstallerXml.Serialize.YesNoType.yes, Microsoft.Tools.WindowsInstallerXml.Serialize.YesNoType.yes, "[ASPNETISAPIDLL]", "GET,HEAD,POST"));
            list.Add(CreateNewWebAppExtension("adprototype", Microsoft.Tools.WindowsInstallerXml.Serialize.YesNoType.yes, Microsoft.Tools.WindowsInstallerXml.Serialize.YesNoType.yes, "[ASPNETISAPIDLL]", "GET,HEAD,POST"));
            list.Add(CreateNewWebAppExtension("asax", Microsoft.Tools.WindowsInstallerXml.Serialize.YesNoType.yes, Microsoft.Tools.WindowsInstallerXml.Serialize.YesNoType.yes, "[ASPNETISAPIDLL]", "GET,HEAD,POST"));
            list.Add(CreateNewWebAppExtension("ascx", Microsoft.Tools.WindowsInstallerXml.Serialize.YesNoType.yes, Microsoft.Tools.WindowsInstallerXml.Serialize.YesNoType.yes, "[ASPNETISAPIDLL]", "GET,HEAD,POST"));
            list.Add(CreateNewWebAppExtension("ashx", Microsoft.Tools.WindowsInstallerXml.Serialize.YesNoType.no, Microsoft.Tools.WindowsInstallerXml.Serialize.YesNoType.yes, "[ASPNETISAPIDLL]", "GET,HEAD,POST"));
            list.Add(CreateNewWebAppExtension("asmx", Microsoft.Tools.WindowsInstallerXml.Serialize.YesNoType.no, Microsoft.Tools.WindowsInstallerXml.Serialize.YesNoType.yes, "[ASPNETISAPIDLL]", "GET,HEAD,POST"));
            list.Add(CreateNewWebAppExtension("aspx", Microsoft.Tools.WindowsInstallerXml.Serialize.YesNoType.no, Microsoft.Tools.WindowsInstallerXml.Serialize.YesNoType.yes, "[ASPNETISAPIDLL]", "GET,HEAD,POST"));
            list.Add(CreateNewWebAppExtension("axd", Microsoft.Tools.WindowsInstallerXml.Serialize.YesNoType.no, Microsoft.Tools.WindowsInstallerXml.Serialize.YesNoType.yes, "[ASPNETISAPIDLL]", "GET,HEAD,POST"));
            list.Add(CreateNewWebAppExtension("browser", Microsoft.Tools.WindowsInstallerXml.Serialize.YesNoType.yes, Microsoft.Tools.WindowsInstallerXml.Serialize.YesNoType.yes, "[ASPNETISAPIDLL]", "GET,HEAD,POST"));
            list.Add(CreateNewWebAppExtension("cd", Microsoft.Tools.WindowsInstallerXml.Serialize.YesNoType.yes, Microsoft.Tools.WindowsInstallerXml.Serialize.YesNoType.yes, "[ASPNETISAPIDLL]", "GET,HEAD,POST"));
            list.Add(CreateNewWebAppExtension("compiled", Microsoft.Tools.WindowsInstallerXml.Serialize.YesNoType.yes, Microsoft.Tools.WindowsInstallerXml.Serialize.YesNoType.yes, "[ASPNETISAPIDLL]", "GET,HEAD,POST"));
            list.Add(CreateNewWebAppExtension("config", Microsoft.Tools.WindowsInstallerXml.Serialize.YesNoType.yes, Microsoft.Tools.WindowsInstallerXml.Serialize.YesNoType.yes, "[ASPNETISAPIDLL]", "GET,HEAD,POST"));
            list.Add(CreateNewWebAppExtension("csproj", Microsoft.Tools.WindowsInstallerXml.Serialize.YesNoType.yes, Microsoft.Tools.WindowsInstallerXml.Serialize.YesNoType.yes, "[ASPNETISAPIDLL]", "GET,HEAD,POST"));
            list.Add(CreateNewWebAppExtension("dd", Microsoft.Tools.WindowsInstallerXml.Serialize.YesNoType.yes, Microsoft.Tools.WindowsInstallerXml.Serialize.YesNoType.yes, "[ASPNETISAPIDLL]", "GET,HEAD,POST"));
            list.Add(CreateNewWebAppExtension("exclude", Microsoft.Tools.WindowsInstallerXml.Serialize.YesNoType.yes, Microsoft.Tools.WindowsInstallerXml.Serialize.YesNoType.yes, "[ASPNETISAPIDLL]", "GET,HEAD,POST"));
            list.Add(CreateNewWebAppExtension("java", Microsoft.Tools.WindowsInstallerXml.Serialize.YesNoType.yes, Microsoft.Tools.WindowsInstallerXml.Serialize.YesNoType.yes, "[ASPNETISAPIDLL]", "GET,HEAD,POST"));
            list.Add(CreateNewWebAppExtension("jsl", Microsoft.Tools.WindowsInstallerXml.Serialize.YesNoType.yes, Microsoft.Tools.WindowsInstallerXml.Serialize.YesNoType.yes, "[ASPNETISAPIDLL]", "GET,HEAD,POST"));
            list.Add(CreateNewWebAppExtension("ldb", Microsoft.Tools.WindowsInstallerXml.Serialize.YesNoType.yes, Microsoft.Tools.WindowsInstallerXml.Serialize.YesNoType.yes, "[ASPNETISAPIDLL]", "GET,HEAD,POST"));
            list.Add(CreateNewWebAppExtension("ldd", Microsoft.Tools.WindowsInstallerXml.Serialize.YesNoType.yes, Microsoft.Tools.WindowsInstallerXml.Serialize.YesNoType.yes, "[ASPNETISAPIDLL]", "GET,HEAD,POST"));
            list.Add(CreateNewWebAppExtension("lddprototype", Microsoft.Tools.WindowsInstallerXml.Serialize.YesNoType.yes, Microsoft.Tools.WindowsInstallerXml.Serialize.YesNoType.yes, "[ASPNETISAPIDLL]", "GET,HEAD,POST"));
            list.Add(CreateNewWebAppExtension("ldf", Microsoft.Tools.WindowsInstallerXml.Serialize.YesNoType.yes, Microsoft.Tools.WindowsInstallerXml.Serialize.YesNoType.yes, "[ASPNETISAPIDLL]", "GET,HEAD,POST"));
            list.Add(CreateNewWebAppExtension("licx", Microsoft.Tools.WindowsInstallerXml.Serialize.YesNoType.yes, Microsoft.Tools.WindowsInstallerXml.Serialize.YesNoType.yes, "[ASPNETISAPIDLL]", "GET,HEAD,POST"));
            list.Add(CreateNewWebAppExtension("master", Microsoft.Tools.WindowsInstallerXml.Serialize.YesNoType.yes, Microsoft.Tools.WindowsInstallerXml.Serialize.YesNoType.yes, "[ASPNETISAPIDLL]", "GET,HEAD,POST"));
            list.Add(CreateNewWebAppExtension("mdb", Microsoft.Tools.WindowsInstallerXml.Serialize.YesNoType.yes, Microsoft.Tools.WindowsInstallerXml.Serialize.YesNoType.yes, "[ASPNETISAPIDLL]", "GET,HEAD,POST"));
            list.Add(CreateNewWebAppExtension("mdf", Microsoft.Tools.WindowsInstallerXml.Serialize.YesNoType.yes, Microsoft.Tools.WindowsInstallerXml.Serialize.YesNoType.yes, "[ASPNETISAPIDLL]", "GET,HEAD,POST"));
            list.Add(CreateNewWebAppExtension("msgx", Microsoft.Tools.WindowsInstallerXml.Serialize.YesNoType.no, Microsoft.Tools.WindowsInstallerXml.Serialize.YesNoType.yes, "[ASPNETISAPIDLL]", "GET,HEAD,POST"));
            list.Add(CreateNewWebAppExtension("refresh", Microsoft.Tools.WindowsInstallerXml.Serialize.YesNoType.yes, Microsoft.Tools.WindowsInstallerXml.Serialize.YesNoType.yes, "[ASPNETISAPIDLL]", "GET,HEAD,POST"));
            list.Add(CreateNewWebAppExtension("rem", Microsoft.Tools.WindowsInstallerXml.Serialize.YesNoType.no, Microsoft.Tools.WindowsInstallerXml.Serialize.YesNoType.yes, "[ASPNETISAPIDLL]", "GET,HEAD,POST"));
            list.Add(CreateNewWebAppExtension("resources", Microsoft.Tools.WindowsInstallerXml.Serialize.YesNoType.yes, Microsoft.Tools.WindowsInstallerXml.Serialize.YesNoType.yes, "[ASPNETISAPIDLL]", "GET,HEAD,POST"));
            list.Add(CreateNewWebAppExtension("resx", Microsoft.Tools.WindowsInstallerXml.Serialize.YesNoType.yes, Microsoft.Tools.WindowsInstallerXml.Serialize.YesNoType.yes, "[ASPNETISAPIDLL]", "GET,HEAD,POST"));
            list.Add(CreateNewWebAppExtension("sd", Microsoft.Tools.WindowsInstallerXml.Serialize.YesNoType.yes, Microsoft.Tools.WindowsInstallerXml.Serialize.YesNoType.yes, "[ASPNETISAPIDLL]", "GET,HEAD,POST"));
            list.Add(CreateNewWebAppExtension("sdm", Microsoft.Tools.WindowsInstallerXml.Serialize.YesNoType.yes, Microsoft.Tools.WindowsInstallerXml.Serialize.YesNoType.yes, "[ASPNETISAPIDLL]", "GET,HEAD,POST"));
            list.Add(CreateNewWebAppExtension("sdmDocument", Microsoft.Tools.WindowsInstallerXml.Serialize.YesNoType.yes, Microsoft.Tools.WindowsInstallerXml.Serialize.YesNoType.yes, "[ASPNETISAPIDLL]", "GET,HEAD,POST"));
            list.Add(CreateNewWebAppExtension("sitemape", Microsoft.Tools.WindowsInstallerXml.Serialize.YesNoType.yes, Microsoft.Tools.WindowsInstallerXml.Serialize.YesNoType.yes, "[ASPNETISAPIDLL]", "GET,HEAD,POST"));
            list.Add(CreateNewWebAppExtension("skin", Microsoft.Tools.WindowsInstallerXml.Serialize.YesNoType.yes, Microsoft.Tools.WindowsInstallerXml.Serialize.YesNoType.yes, "[ASPNETISAPIDLL]", "GET,HEAD,POST"));
            list.Add(CreateNewWebAppExtension("soap", Microsoft.Tools.WindowsInstallerXml.Serialize.YesNoType.no, Microsoft.Tools.WindowsInstallerXml.Serialize.YesNoType.yes, "[ASPNETISAPIDLL]", "GET,HEAD,POST"));
            list.Add(CreateNewWebAppExtension("svc", Microsoft.Tools.WindowsInstallerXml.Serialize.YesNoType.no, Microsoft.Tools.WindowsInstallerXml.Serialize.YesNoType.yes, "[ASPNETISAPIDLL]", "GET,HEAD,POST"));
            list.Add(CreateNewWebAppExtension("vb", Microsoft.Tools.WindowsInstallerXml.Serialize.YesNoType.yes, Microsoft.Tools.WindowsInstallerXml.Serialize.YesNoType.yes, "[ASPNETISAPIDLL]", "GET,HEAD,POST"));
            list.Add(CreateNewWebAppExtension("vbproj", Microsoft.Tools.WindowsInstallerXml.Serialize.YesNoType.yes, Microsoft.Tools.WindowsInstallerXml.Serialize.YesNoType.yes, "[ASPNETISAPIDLL]", "GET,HEAD,POST"));
            list.Add(CreateNewWebAppExtension("vjsproj", Microsoft.Tools.WindowsInstallerXml.Serialize.YesNoType.yes, Microsoft.Tools.WindowsInstallerXml.Serialize.YesNoType.yes, "[ASPNETISAPIDLL]", "GET,HEAD,POST"));
            list.Add(CreateNewWebAppExtension("vsdisco", Microsoft.Tools.WindowsInstallerXml.Serialize.YesNoType.no, Microsoft.Tools.WindowsInstallerXml.Serialize.YesNoType.yes, "[ASPNETISAPIDLL]", "GET,HEAD,POST"));
            list.Add(CreateNewWebAppExtension("webinfo", Microsoft.Tools.WindowsInstallerXml.Serialize.YesNoType.yes, Microsoft.Tools.WindowsInstallerXml.Serialize.YesNoType.yes, "[ASPNETISAPIDLL]", "GET,HEAD,POST"));

            return list;
        }
                
        private Microsoft.Tools.WindowsInstallerXml.Serialize.WebSite GenerateWixWebSite(WebSite webSite)
        {
            Microsoft.Tools.WindowsInstallerXml.Serialize.WebSite wixWebSite = new Microsoft.Tools.WindowsInstallerXml.Serialize.WebSite();

            wixWebSite.Id = webSite.Name;
            wixWebSite.Description = webSite.Name;
            wixWebSite.DirProperties = webSite.DirProperties.Name;
            wixWebSite.Directory = GetDirectoryId(webSite);

            Microsoft.Tools.WindowsInstallerXml.Serialize.WebAddress webAddress = new Microsoft.Tools.WindowsInstallerXml.Serialize.WebAddress();
            webAddress.Id = String.Format("{0}_webAddress", webSite.Name);
            webAddress.Port = webSite.Port.ToString();

            wixWebSite.AddChild(webAddress);

            return wixWebSite;
        }

        private Microsoft.Tools.WindowsInstallerXml.Serialize.WebAppPool GenerateWixApplicationPool(IISApplicationPool iisPool)
        {
            Microsoft.Tools.WindowsInstallerXml.Serialize.WebAppPool appPool = new Microsoft.Tools.WindowsInstallerXml.Serialize.WebAppPool();
            appPool.Id = iisPool.Name;
            appPool.Name = iisPool.Name;
            appPool.Identity = (Microsoft.Tools.WindowsInstallerXml.Serialize.WebAppPool.IdentityType)Enum.Parse(
                typeof(Microsoft.Tools.WindowsInstallerXml.Serialize.WebAppPool.IdentityType),
                iisPool.Identity.ToString());

            if (appPool.Identity == Microsoft.Tools.WindowsInstallerXml.Serialize.WebAppPool.IdentityType.other)
            {
                appPool.User = GetAppPoolUserId(iisPool);
            }

            return appPool;
        }

        private Microsoft.Tools.WindowsInstallerXml.Serialize.User GenerateWixUserForAppPool(IISApplicationPool appPool)
        {
            Microsoft.Tools.WindowsInstallerXml.Serialize.User user = new Microsoft.Tools.WindowsInstallerXml.Serialize.User();
            user.Id = GetAppPoolUserId(appPool);
            user.Name = GetAppPoolUserNameProperty(appPool);
            user.Domain = GetAppPoolUserDomainProperty(appPool);
            user.Password = GetAppPoolUserDomainProperty(appPool);
            user.UpdateIfExists = Microsoft.Tools.WindowsInstallerXml.Serialize.YesNoType.no;
            user.RemoveOnUninstall = Microsoft.Tools.WindowsInstallerXml.Serialize.YesNoType.no;
            user.FailIfExists = Microsoft.Tools.WindowsInstallerXml.Serialize.YesNoType.no;
            
            return user;
        }
        

        private Microsoft.Tools.WindowsInstallerXml.Serialize.WebDirProperties GenerateWixWebDirProperties(VirtualDirectoryProperties vdirProp)
        {
            Microsoft.Tools.WindowsInstallerXml.Serialize.WebDirProperties webDirProperty = new Microsoft.Tools.WindowsInstallerXml.Serialize.WebDirProperties();
            webDirProperty.Id = vdirProp.Name;
            webDirProperty.BasicAuthentication = MapBooleanToYesNoType(vdirProp.BasicAuthentication);
            webDirProperty.Execute = MapBooleanToYesNoType(vdirProp.Execute);
            webDirProperty.Index = MapBooleanToYesNoType(vdirProp.Index);
            webDirProperty.LogVisits = MapBooleanToYesNoType(vdirProp.LogVisits);
            webDirProperty.Script = MapBooleanToYesNoType(vdirProp.Script);
            webDirProperty.Read = MapBooleanToYesNoType(vdirProp.Read);
            webDirProperty.WindowsAuthentication = MapBooleanToYesNoType(vdirProp.WindowsAuthentication);
            webDirProperty.PassportAuthentication = MapBooleanToYesNoType(vdirProp.PassportAuthentication);
            webDirProperty.DigestAuthentication = MapBooleanToYesNoType(vdirProp.DigestAuthentication);
            webDirProperty.AnonymousAccess = MapBooleanToYesNoType(vdirProp.AnonymousAccess);


            return webDirProperty;
        }

        private Microsoft.Tools.WindowsInstallerXml.Serialize.YesNoType MapBooleanToYesNoType(Boolean value)
        {
            return value ? Microsoft.Tools.WindowsInstallerXml.Serialize.YesNoType.yes : Microsoft.Tools.WindowsInstallerXml.Serialize.YesNoType.no;
        }

        public Microsoft.Tools.WindowsInstallerXml.Serialize.Fragment GenerateWebApplications(WebAspApplication app)
        {
            Microsoft.Tools.WindowsInstallerXml.Serialize.Fragment fragment = new Microsoft.Tools.WindowsInstallerXml.Serialize.Fragment();
            Microsoft.Tools.WindowsInstallerXml.Serialize.DirectoryRef targetRef = new Microsoft.Tools.WindowsInstallerXml.Serialize.DirectoryRef();
            targetRef.Id = "TARGETDIR";

            targetRef.AddChild(GetIISApplicationComponent(app, true));
            targetRef.AddChild(GetIISApplicationComponent(app, false));

            fragment.AddChild(targetRef);

            return fragment;
        }

        private Microsoft.Tools.WindowsInstallerXml.Serialize.Component GetIISApplicationComponent(WebAspApplication app, bool IIS50)
        {
            Microsoft.Tools.WindowsInstallerXml.Serialize.Component component = new Microsoft.Tools.WindowsInstallerXml.Serialize.Component();
            component.Id = GetWebVirtualDirComponentId(app, IIS50);
            component.Guid = GetComponentGuid(component.Id);
            component.Permanent = Microsoft.Tools.WindowsInstallerXml.Serialize.YesNoType.no;
            IISHosted hosted = IISHosted.GetLinkToIIS(app);

            if (!IIS50)
                component.AddChild(GetIIS60Condition());

            Microsoft.Tools.WindowsInstallerXml.Serialize.WebVirtualDir webVDir = new Microsoft.Tools.WindowsInstallerXml.Serialize.WebVirtualDir();
            webVDir.Id = GetWebVirtualDirId(app, IIS50);
            webVDir.Alias = app.VirtualPath;
            webVDir.Directory = GetDirectoryId(app);
            webVDir.DirProperties = hosted.VirtualDirectoryProperty.Name;
            webVDir.WebSite = hosted.WebSite.Name;

            Microsoft.Tools.WindowsInstallerXml.Serialize.WebApplication webApp = new Microsoft.Tools.WindowsInstallerXml.Serialize.WebApplication();
            webApp.Id = GetWebAppId(app, IIS50);
            webApp.Isolation = (Microsoft.Tools.WindowsInstallerXml.Serialize.WebApplication.IsolationType)Enum.Parse(typeof(Microsoft.Tools.WindowsInstallerXml.Serialize.WebApplication.IsolationType), app.IsolationLevel.ToString());
            webApp.Name = app.Name;
            foreach(Microsoft.Tools.WindowsInstallerXml.Serialize.WebApplicationExtension ext in GetWebAppExtensionsForAspNet2_0())
                webApp.AddChild(ext);

            if (!IIS50 && hosted != null && hosted.AppPool != null)
                webApp.WebAppPool = hosted.AppPool.Name;

            webVDir.AddChild(webApp);
            component.AddChild(webVDir);

            return component;
        }

        private Microsoft.Tools.WindowsInstallerXml.Serialize.Condition GetIIS60Condition()
        {
            Microsoft.Tools.WindowsInstallerXml.Serialize.Condition condition = new Microsoft.Tools.WindowsInstallerXml.Serialize.Condition();
            condition.Content = "IISVERSION>5";
            return condition;
        }

        private string GetAppPoolUserId(IISApplicationPool appPool)
        {
            return String.Format("(0)_AppPoolUser", appPool.Name);
        }

        private string GetAppPoolUserComponentId(IISApplicationPool appPool)
        {
            return String.Format("(0)_AppPoolUser_C", appPool.Name);
        }

        private string GetAppPoolUserNameProperty(IISApplicationPool appPool)
        {
            return String.Format("(0).APPPOOL.USERNAME", appPool.Name.ToUpper());
        }

        private string GetAppPoolUserPasswordProperty(IISApplicationPool appPool)
        {
            return String.Format("(0).APPPOOL.USERPASSWORD", appPool.Name.ToUpper());
        }

        private string GetAppPoolUserDomainProperty(IISApplicationPool appPool)
        {
            return String.Format("(0).APPPOOL.USERDOMAIN", appPool.Name.ToUpper());
        }

        private string GetWebAppId(WebAspApplication app, bool IIS50)
        {
            return String.Format("{0}_WebApplication{1}", app.Name, (IIS50 ? "5" : "6"));
        }

        private string GetWebVirtualDirComponentId(WebAspApplication app, bool IIS50)
        {
            return String.Format("{0}_VC{1}", app.Name, (IIS50 ? "5" : "6"));
        }

        private string GetWebSiteComponentId(WebSite webSite)
        {
            return String.Format("{0}_WSC{1}", webSite.Name);
        }

        private string GetAppPoolComponentId(IISApplicationPool appPool)
        {
            return String.Format("{0}_APC{1}", appPool.Name);
        }

        private string GetWebVirtualDirId(WebAspApplication app, bool IIS50)
        {
            return String.Format("{0}_WebVirtualDir{1}", app.Name, (IIS50 ? "5" : "6"));
        }

        private string GetDirectoryId(NamedElement app)
        {
            throw new Exception("The method or operation is not implemented.");
        }

        private string GetComponentGuid(string p)
        {
            throw new Exception("The method or operation is not implemented.");
        }

        private String GetDirectoryId(String Path)
        {
            //int i = Path.LastIndexOf(System.IO.Path.DirectorySeparatorChar);
            //if (i == -1)
            //    return "";
            //else
            //    return Path.Substring(i).ToUpper() + GetElementGuid(Path);
            return "";
        }

        #region Directory Model
        public Microsoft.Tools.WindowsInstallerXml.Serialize.Directory CreateComponentHostDirectoryStructure(Guid domainClassId)
        {
            if (domainClassId.Equals(WebAspApplication.DomainClassId))
            {
                return CreateIISDirectoryStructure();
            }
            else if (domainClassId.Equals(PlumtreeImage.DomainClassId))
            {
                return CreatePTImagesDirectoryStructure();
            }
            else if (domainClassId.Equals(JavaWebApplication.DomainClassId))
            {
                return CreateTomcatDirectoryStructure();
            }
            else if (domainClassId.Equals(PTCustomization.DomainClassId))
            {
                return CreatePTCustomizationDirectoryStructure();
            }

            return null;
        }

        private Microsoft.Tools.WindowsInstallerXml.Serialize.Directory CreateFileDirectoryStructure()
        {
            return null;
        }

        private Microsoft.Tools.WindowsInstallerXml.Serialize.Directory CreatePTCustomizationDirectoryStructure()
        {
            return CreateDirectory("PLUMTREE_DIR", "Plumtree", "Plumtree");
        }

        private Microsoft.Tools.WindowsInstallerXml.Serialize.Directory CreateTomcatDirectoryStructure()
        {
            Microsoft.Tools.WindowsInstallerXml.Serialize.Directory rootDir = CreateDirectory("TOMCAT_DIR", "Tomcat", "Tomcat");
            Microsoft.Tools.WindowsInstallerXml.Serialize.Directory webAppDir = CreateDirectory("TOMCAT_WEBAPP_DIR", "webapps", "webapps");
            Microsoft.Tools.WindowsInstallerXml.Serialize.Directory contextDir = CreateDirectory("TOMCAT_CONTEXT_DIR", "configs", "configs");

            rootDir.AddChild(webAppDir);
            rootDir.AddChild(contextDir);

            return rootDir;
        }

        private Microsoft.Tools.WindowsInstallerXml.Serialize.Directory CreatePTImagesDirectoryStructure()
        {
            return CreateDirectory("PTIMAGE_DIR", "Plumtree", "Plumtree");
        }

        private Microsoft.Tools.WindowsInstallerXml.Serialize.Directory CreateIISDirectoryStructure()
        {
            return CreateDirectory("WWWROOT_DIR", "WWWRoot", "WWWRoot");
        }

        private Microsoft.Tools.WindowsInstallerXml.Serialize.Directory CreateDirectory(String Id, String Name, String Source)
        {
            Microsoft.Tools.WindowsInstallerXml.Serialize.Directory dir = new Microsoft.Tools.WindowsInstallerXml.Serialize.Directory();
            dir.Id = Id;
            dir.Name = Name;
            dir.SourceName = Source;
            dir.LongName = Name;


            return dir;
        }

        private Microsoft.Tools.WindowsInstallerXml.Serialize.Directory GetComponentDirectory(Component component, Microsoft.Tools.WindowsInstallerXml.Serialize.Directory rootDir)
        {
            if (component.ComponentPackage != null)
            {
                Microsoft.Tools.WindowsInstallerXml.Serialize.Directory dir = GetComponentPackageDirectory(component.ComponentPackage, rootDir);
                //dir.AddChild(CreateDirectory(GetDirectoryId(component), component.Name, component.Name));
                return dir;
            }
            else
                return rootDir;// CreateDirectory(GetDirectoryId(component), component.Name, component.Name);
        }

        private Microsoft.Tools.WindowsInstallerXml.Serialize.Directory GetComponentPackageDirectory(ComponentPackage component, Microsoft.Tools.WindowsInstallerXml.Serialize.Directory rootDir)
        {
            if (component.ParentPackage == null)
            {
                Microsoft.Tools.WindowsInstallerXml.Serialize.Directory dir = FindDirectory(rootDir, GetDirectoryId(component));
                if (dir == null)
                {
                    dir = CreateDirectory(GetDirectoryId(component), component.Name, component.Name);
                    rootDir.AddChild(dir);
                }

                return dir;
            }
            else
            {
                Microsoft.Tools.WindowsInstallerXml.Serialize.Directory dir = GetComponentPackageDirectory(component.ParentPackage, rootDir);
                Microsoft.Tools.WindowsInstallerXml.Serialize.Directory dir1 = FindDirectory(rootDir, GetDirectoryId(component));
                if (dir1 == null)
                {
                    dir1 = CreateDirectory(GetDirectoryId(component), component.Name, component.Name);
                    dir.AddChild(dir1);
                }

                return dir;
            }
        }

        public Microsoft.Tools.WindowsInstallerXml.Serialize.Directory FindDirectory(String dirId)
        {
            Microsoft.Tools.WindowsInstallerXml.Serialize.Wix wix = GetWixModel();

            foreach (Microsoft.Tools.WindowsInstallerXml.Serialize.ISchemaElement element in wix.Children)
            {
                if (element.GetType().Equals(typeof(Microsoft.Tools.WindowsInstallerXml.Serialize.Product)) ||
                    element.GetType().Equals(typeof(Microsoft.Tools.WindowsInstallerXml.Serialize.Fragment)))
                {
                    foreach (Microsoft.Tools.WindowsInstallerXml.Serialize.ISchemaElement element1 in (System.Collections.IEnumerable)element.GetType().InvokeMember("Children", System.Reflection.BindingFlags.GetProperty, null, element, null))
                    {
                        if (element1.GetType().Equals(typeof(Microsoft.Tools.WindowsInstallerXml.Serialize.Directory)))
                        {
                            if ((element1 as Microsoft.Tools.WindowsInstallerXml.Serialize.Directory).Id.Equals(dirId))
                                return element1 as Microsoft.Tools.WindowsInstallerXml.Serialize.Directory;
                            else
                            {
                                object d = FindDirectory(element1 as Microsoft.Tools.WindowsInstallerXml.Serialize.Directory, dirId);
                                if (d != null)
                                    return d as Microsoft.Tools.WindowsInstallerXml.Serialize.Directory;
                            }
                        }
                    }
                }
            }

            return null;
        }

        public Microsoft.Tools.WindowsInstallerXml.Serialize.Wix GetWixModel()
        {
            if (this.Store.PropertyBag.ContainsKey("currentWixModel"))
                return this.Store.PropertyBag["currentWixModel"] as Microsoft.Tools.WindowsInstallerXml.Serialize.Wix;
            else
            {
                Microsoft.Tools.WindowsInstallerXml.Serialize.Wix wix = CreateWixModel();
                this.Store.PropertyBag["currentWixModel"] = wix;
                return wix;
            }
        }

        private Microsoft.Tools.WindowsInstallerXml.Serialize.Wix CreateWixModel()
        {
            Microsoft.Tools.WindowsInstallerXml.Serialize.Wix wix = new Microsoft.Tools.WindowsInstallerXml.Serialize.Wix();

            return wix;
        }

        private Microsoft.Tools.WindowsInstallerXml.Serialize.Directory FindDirectory(Microsoft.Tools.WindowsInstallerXml.Serialize.Directory dir, String dirId)
        {
            foreach (Microsoft.Tools.WindowsInstallerXml.Serialize.ISchemaElement d in dir.Children)
            {
                if (d.GetType().Equals(typeof(Microsoft.Tools.WindowsInstallerXml.Serialize.Directory)))
                {
                    if ((d as Microsoft.Tools.WindowsInstallerXml.Serialize.Directory).Id.Equals(dirId))
                        return d as Microsoft.Tools.WindowsInstallerXml.Serialize.Directory;
                    else
                    {
                        object d1 = FindDirectory(d as Microsoft.Tools.WindowsInstallerXml.Serialize.Directory, dirId);
                        if (d1 != null)
                            return d1 as Microsoft.Tools.WindowsInstallerXml.Serialize.Directory;
                    }
                }
            }

            return null;
        }

        private Microsoft.Tools.WindowsInstallerXml.Serialize.Directory GetComponentDirectory(Microsoft.Tools.WindowsInstallerXml.Serialize.Directory targetDir, Component component)
        {
            Guid domainClassId = component.GetDomainClass().Id;

            if (domainClassId.Equals(WebAspApplication.DomainClassId))
            {
                Microsoft.Tools.WindowsInstallerXml.Serialize.Directory wwwRootDir = FindDirectory(targetDir, "WWWROOT_DIR");
                if (wwwRootDir == null)
                    wwwRootDir = CreateComponentHostDirectoryStructure(domainClassId);

                return GetComponentDirectory(component, wwwRootDir);
            }
            else if (domainClassId.Equals(PlumtreeImage.DomainClassId))
            {
                return CreatePTImagesDirectoryStructure();
            }
            else if (domainClassId.Equals(JavaWebApplication.DomainClassId))
            {
                return CreateTomcatDirectoryStructure();
            }
            else if (domainClassId.Equals(PTCustomization.DomainClassId))
            {
                return CreatePTCustomizationDirectoryStructure();
            }


            return null;
        }

        #endregion

        #region WebContainer
        public void GenerateJavaWebContainerWixCode(JavaWebContainer javaWebContainer)
        {
            Microsoft.Tools.WindowsInstallerXml.Serialize.Fragment fragment = GetCurrentFragment();
            Microsoft.Tools.WindowsInstallerXml.Serialize.Directory dir = CreateDirectory(GetDirectoryId(javaWebContainer.Name), javaWebContainer.Name, null);
            fragment.AddChild(dir);

            Microsoft.Tools.WindowsInstallerXml.Serialize.Property p = GetWixProperty(GetDirectoryId(javaWebContainer.Name), null);
            
            Microsoft.Tools.WindowsInstallerXml.Serialize.RegistrySearch rs = new Microsoft.Tools.WindowsInstallerXml.Serialize.RegistrySearch();
            rs.Id = "Find" + javaWebContainer.Name + "HomeDir";
            rs.Type = Microsoft.Tools.WindowsInstallerXml.Serialize.RegistrySearch.TypeType.raw;
            rs.Root = Microsoft.Tools.WindowsInstallerXml.Serialize.RegistrySearch.RootType.HKLM;
            rs.Key = @"SOFTWARE\Apache Software Foundation\Tomcat\5.5";
            rs.Name = "InstallPath";
            
            p.AddChild(rs);

            fragment.AddChild(p);

            Microsoft.Tools.WindowsInstallerXml.Serialize.Directory common_dir = CreateDirectory(GetDirectoryId(javaWebContainer.Name + ".COMMON"), "common", "common");
            dir.AddChild(common_dir);
            Microsoft.Tools.WindowsInstallerXml.Serialize.Directory c_lib_dir = CreateDirectory(GetDirectoryId(javaWebContainer.Name + ".COMMON.LIB"), "lib", "lib");
            common_dir.AddChild(c_lib_dir);

            Microsoft.Tools.WindowsInstallerXml.Serialize.Directory shared_dir = CreateDirectory(GetDirectoryId(javaWebContainer.Name + ".SHARED"), "shared", "shared");
            dir.AddChild(shared_dir);
            Microsoft.Tools.WindowsInstallerXml.Serialize.Directory s_lib_dir = CreateDirectory(GetDirectoryId(javaWebContainer.Name + ".SHARED.LIB"), "lib", "lib");
            shared_dir.AddChild(s_lib_dir);

            foreach (FolderSource fs in javaWebContainer.Libs)
            {
                if (fs.FileSystem == null)
                    continue;

                JavaWebContainerHasLibs link = JavaWebContainerHasLibs.GetLink(javaWebContainer, fs);
                switch (link.Type)
                {
                    case WebContainerLibraryType.common:
                        dir = c_lib_dir;
                        break;
                    case WebContainerLibraryType.shared:
                        dir = s_lib_dir;
                        break;
                }

                foreach (FileModel lib in fs.FileSystem.Partition.ElementDirectory.FindElements(FileModel.DomainClassId, true))
                {
                    dir.AddChild(GenerateWixComponentModel(lib));
                }
            }
           }

        private Microsoft.Tools.WindowsInstallerXml.Serialize.ISchemaElement GenerateWixComponentModel(FileModel lib)
        {
            throw new Exception("The method or operation is not implemented.");
        }

        private Microsoft.Tools.WindowsInstallerXml.Serialize.Property GetWixProperty(string p, object p_2)
        {
            throw new Exception("The method or operation is not implemented.");
        }

        private Microsoft.Tools.WindowsInstallerXml.Serialize.Fragment GetCurrentFragment()
        {
            throw new Exception("The method or operation is not implemented.");
        }
        #endregion


        public Microsoft.Tools.WindowsInstallerXml.Serialize.Property GetAntExeProperty()
        {
            /*
            <Property Id="ANT_EXE">
              <ComponentSearch Id="FindAntExe" Guid="{349B9607-366E-3F3D-AA74-D63AA911DEB2}" Type="file">
                <FileSearch Id="FindAnt" LongName="ant.bat" Name="ant.bat" />
              </ComponentSearch>
            </Property>
            */

            Microsoft.Tools.WindowsInstallerXml.Serialize.Property property = new Microsoft.Tools.WindowsInstallerXml.Serialize.Property();
            property.Id = "ANT_EXE";
            Microsoft.Tools.WindowsInstallerXml.Serialize.ComponentSearch compSearch = new Microsoft.Tools.WindowsInstallerXml.Serialize.ComponentSearch();
            compSearch.Id = "FindAntExe";
            compSearch.Guid = "{349B9607-366E-3F3D-AA74-D63AA911DEB2}";
            compSearch.Type = Microsoft.Tools.WindowsInstallerXml.Serialize.ComponentSearch.TypeType.file;
            Microsoft.Tools.WindowsInstallerXml.Serialize.FileSearch fileSearch = new Microsoft.Tools.WindowsInstallerXml.Serialize.FileSearch();
            fileSearch.Id = "FindAntExeFile";
            fileSearch.Name = "ant.bat";
            compSearch.AddChild(fileSearch);
            property.AddChild(compSearch);

            return property;
	    }

        private void GenerateSupportFilesDirStructure(WindowsService component)
        {
            GenerateSupportFilesDirStructure(component as Component,
                new FileSystemProcessor(delegate(Microsoft.Tools.WindowsInstallerXml.Serialize.Directory dir)
                {
                    DirectoryTraversor(dir, new ComponentProcessor(delegate(Microsoft.Tools.WindowsInstallerXml.Serialize.Component cmp)
                    {
                        foreach (Microsoft.Tools.WindowsInstallerXml.Serialize.File file in cmp[typeof(Microsoft.Tools.WindowsInstallerXml.Serialize.File)])
                        {
                            if (String.Compare(file.LongName, component.ServiceFileName, true) == 0)
                            {
                                file.KeyPath = Microsoft.Tools.WindowsInstallerXml.Serialize.YesNoType.yes;
                                AddWindowsService2ServiceInstall(cmp, component);
                            }
                        }                            
                    }));
                }));
        }

        private void AddWindowsService2ServiceInstall(Microsoft.Tools.WindowsInstallerXml.Serialize.Component cmp, WindowsService winSvc)
        {
            Microsoft.Tools.WindowsInstallerXml.Serialize.ServiceInstall serviceInstall = new Microsoft.Tools.WindowsInstallerXml.Serialize.ServiceInstall();
            serviceInstall.DisplayName = winSvc.DisplayName;
            serviceInstall.Name = winSvc.ServiceName;
            serviceInstall.Start = MapServiceStartType2WixStartType(winSvc.Start);
            serviceInstall.Description = winSvc.Description;
            serviceInstall.ErrorControl = Microsoft.Tools.WindowsInstallerXml.Serialize.ServiceInstall.ErrorControlType.normal;
            serviceInstall.Id = String.Format("Install{0}", winSvc.ServiceName);
            serviceInstall.Type = MapWinService2wixServiceType(winSvc);
            serviceInstall.Account = MapServiceIdentity2WixAccount(winSvc);
            serviceInstall.Password = MapServiceIdentity2WixPassword(winSvc);
            cmp.AddChild(serviceInstall);

            Microsoft.Tools.WindowsInstallerXml.Serialize.ServiceControl control = new Microsoft.Tools.WindowsInstallerXml.Serialize.ServiceControl();
            control.Id = String.Format("Start{0}", winSvc.ServiceName);
            control.Name = winSvc.ServiceName;
            control.Start = Microsoft.Tools.WindowsInstallerXml.Serialize.ServiceControl.StartType.install;
            control.Wait = Microsoft.Tools.WindowsInstallerXml.Serialize.YesNoType.no;
            cmp.AddChild(control);

            control = new Microsoft.Tools.WindowsInstallerXml.Serialize.ServiceControl();
            control.Id = String.Format("Stop{0}", winSvc.ServiceName);
            control.Name = winSvc.ServiceName;
            control.Stop = Microsoft.Tools.WindowsInstallerXml.Serialize.ServiceControl.StopType.both;
            control.Wait = Microsoft.Tools.WindowsInstallerXml.Serialize.YesNoType.yes;
            control.Remove = Microsoft.Tools.WindowsInstallerXml.Serialize.ServiceControl.RemoveType.uninstall;
            cmp.AddChild(control);
        }

        private Microsoft.Tools.WindowsInstallerXml.Serialize.ServiceInstall.TypeType MapWinService2wixServiceType(WindowsService component)
        {
            switch (component.Identity)
            {
                case IdentityType.other:
                case IdentityType.networkService:
                case IdentityType.localService:
                    return Microsoft.Tools.WindowsInstallerXml.Serialize.ServiceInstall.TypeType.ownProcess;
                case IdentityType.localSystem:
                    return Microsoft.Tools.WindowsInstallerXml.Serialize.ServiceInstall.TypeType.shareProcess;
            }

            return Microsoft.Tools.WindowsInstallerXml.Serialize.ServiceInstall.TypeType.shareProcess;
        }

        private string MapServiceIdentity2WixPassword(WindowsService winSvc)
        {
            switch (winSvc.Identity)
            {
                case IdentityType.other:
                    return String.Format("[{0}]", GetWindowsServiceUserPasswordProperty(winSvc));
            }
            return "";
        }
     
        private string MapServiceIdentity2WixAccount(WindowsService winSvc)
        {
            switch (winSvc.Identity)
            {
                case IdentityType.localService:
                    return "";
                case IdentityType.localSystem:
                    return "";
                case IdentityType.networkService:
                    return @"NT AUTHORITY\NetworkService";
                case IdentityType.other:
                    return String.Format(@"[{1}]\[{0}]", GetWindowsServiceUserNameProperty(winSvc), GetWindowsServiceUserDomainProperty(winSvc));
            }

            return "";
        }

        private string GetWindowsServiceUserPasswordProperty(WindowsService winSvc)
        {
            return String.Format("{0}.USER.PASSWORD", winSvc.ServiceName.ToUpper());
        }

        private string GetWindowsServiceUserDomainProperty(WindowsService winSvc)
        {
            return String.Format("{0}.USER.DOMAIN", winSvc.ServiceName.ToUpper());
        }

        private string GetWindowsServiceUserNameProperty(WindowsService winSvc)
        {
            return String.Format("{0}.USER.NAME", winSvc.ServiceName.ToUpper());
        }

        private Microsoft.Tools.WindowsInstallerXml.Serialize.ServiceInstall.StartType MapServiceStartType2WixStartType(ServiceStartType serviceStartType)
        {
            switch (serviceStartType)
            {
                case ServiceStartType.Auto:
                    return Microsoft.Tools.WindowsInstallerXml.Serialize.ServiceInstall.StartType.auto;
                case ServiceStartType.Demand:
                    return Microsoft.Tools.WindowsInstallerXml.Serialize.ServiceInstall.StartType.demand;
                case ServiceStartType.Disable:
                    return Microsoft.Tools.WindowsInstallerXml.Serialize.ServiceInstall.StartType.disabled;
            }

            return Microsoft.Tools.WindowsInstallerXml.Serialize.ServiceInstall.StartType.auto;
        }

        private void DirectoryTraversor(Microsoft.Tools.WindowsInstallerXml.Serialize.Directory dir, ComponentProcessor cmpProcessor)
        {
            if (cmpProcessor == null)
                return;

            foreach (Microsoft.Tools.WindowsInstallerXml.Serialize.Component component in dir[typeof(Microsoft.Tools.WindowsInstallerXml.Serialize.Component)])
            {
                cmpProcessor(component);
            }
        }

        delegate void ComponentProcessor(Microsoft.Tools.WindowsInstallerXml.Serialize.Component component);

        delegate void FileProcessor(Microsoft.Tools.WindowsInstallerXml.Serialize.File file);

        delegate void FileSystemProcessor(Microsoft.Tools.WindowsInstallerXml.Serialize.Directory dir);

        private void GenerateSupportFilesDirStructure(Component component)
        {
            GenerateSupportFilesDirStructure(component, new FileSystemProcessor(delegate(Microsoft.Tools.WindowsInstallerXml.Serialize.Directory dir){}));
        }

        private void GenerateSupportFilesDirStructure(Component component, FileSystemProcessor processor)
        {
            Microsoft.Tools.WindowsInstallerXml.Serialize.Directory wixDir;
            Microsoft.Tools.WindowsInstallerXml.Serialize.DirectoryRef targetDirRef = GetDirectoryRef("TARGETDIR");
            Microsoft.Tools.WindowsInstallerXml.Serialize.DirectoryRef installDirRef = GetDirectoryRef("Install");
            Microsoft.Tools.WindowsInstallerXml.Serialize.Fragment fragment = GetCurrentFragment();

            if (component.FileSource != null && component.FileSource.FileSystem != null)
            {
                installDirRef.src = Path.Combine("SourceDir", ConvertPathToRelativePath(component.FileSource.FileSystem.Path));

                foreach (DirectoryModel dirModel in component.FileSource.FileSystem.Directories)
                {
                    Microsoft.Tools.WindowsInstallerXml.Serialize.DirectoryRef wixDirRef = GetDirectoryRef(GetDirectoryId(dirModel));
                    wixDir = GenerateWixDirectoriesModel(dirModel);
                    foreach (Microsoft.Tools.WindowsInstallerXml.Serialize.ISchemaElement c in wixDir.Children)
                        wixDirRef.AddChild(c);

                    wixDirRef.src = wixDir.src;
                    fragment.AddChild(wixDirRef);
                }

                //WriteLine("<!-- Install required assemblies to the GAC. Place components in an \"Install\" subdirectory to prevent MSI validation errors. -->");
                wixDir = GenerateWixInstallDirectoryModel(component.FileSource.FileSystem);
                foreach (Microsoft.Tools.WindowsInstallerXml.Serialize.Component c in wixDir.Children)
                    installDirRef.AddChild(c);

                //WriteLine("<!-- Components with Xml modifications -->");
                foreach (Microsoft.Tools.WindowsInstallerXml.Serialize.Component c in GenerateFileActions(component.FileSource))
                {
                    Microsoft.Tools.WindowsInstallerXml.Serialize.ComponentRef cr = new Microsoft.Tools.WindowsInstallerXml.Serialize.ComponentRef();
                    cr.Id = c.Id;
                    GetCurrentComponentGroup().AddChild(cr);
                    targetDirRef.AddChild(c);
                }

                fragment.AddChild(targetDirRef);
                fragment.AddChild(installDirRef);
            }
        }

        private String GetDirectoryId(DirectoryModel dir)
        {
            throw new Exception("The method or operation is not implemented.");
        }

        private IEnumerable<Microsoft.Tools.WindowsInstallerXml.Serialize.Component> GenerateFileActions(ComponentFileSource componentFileSource)
        {
            throw new Exception("The method or operation is not implemented.");
        }

        private Microsoft.Tools.WindowsInstallerXml.Serialize.ComponentGroup GetCurrentComponentGroup()
        {
            throw new Exception("The method or operation is not implemented.");
        }

        private Microsoft.Tools.WindowsInstallerXml.Serialize.Directory GenerateWixInstallDirectoryModel(FileSystemModel fileSystemModel)
        {
            throw new Exception("The method or operation is not implemented.");
        }

        private Microsoft.Tools.WindowsInstallerXml.Serialize.Directory GenerateWixDirectoriesModel(DirectoryModel dirModel)
        {
            throw new Exception("The method or operation is not implemented.");
        }

        private string ConvertPathToRelativePath(string p)
        {
            throw new Exception("The method or operation is not implemented.");
        }

        private Microsoft.Tools.WindowsInstallerXml.Serialize.DirectoryRef GetDirectoryRef(string p)
        {
            throw new Exception("The method or operation is not implemented.");
        }

        private Microsoft.Tools.WindowsInstallerXml.Serialize.DirectoryRef GetDirectoryRef(NamedElement p)
        {
            throw new Exception("The method or operation is not implemented.");
        }
        private Microsoft.Tools.WindowsInstallerXml.Serialize.DirectoryRef GetDirectoryRef(DirectoryModel p)
        {
            throw new Exception("The method or operation is not implemented.");
        }
        
    }
}
